import { isObject } from "../help";
import {arrayMethods} from './array'
import { Dep } from "./dep";
export function defineReactive(obj, key, value, shallow, customSetter){
    shallow = !!shallow
    // 深度监听
    if (!shallow){
        observe(value, false);
    }
    const dep = new Dep();
    Object.defineProperty(obj, key, {
        get(){
            // 收集watcher
            dep.depend();
            return value
        },
        set(val){
            if (customSetter){
                customSetter();
            }
            // 赋值可能是个对象, 需要监听
            if (!shallow){
                observe(val, false);
            }
            value = val;
            // 触发watcher
            dep.notify();
        }
    })
}
let shouldObserve = true;
export function toggleObserving(flag){
    shouldObserve = !!flag;
}
class Observer{
    constructor(value, shallow){
        shallow = !!shallow;
        // 防止递归出现, __ob__ 遍历时候发现还有个this, 继续遍历, 还有个__ob__
        Object.defineProperty(value, '__ob__', {
            value: this,
            enumerable: false
        });
        if (isObject(value)){
            let keys = Object.keys(value);
            for (let i=0; i<keys.length; i++){
                const key = keys[i];
                defineReactive(value, key, value[key], shallow);
            }
        }else if(Array.isArray(value)){
            // 修改数组的 __proto__ 这样就可以让push方法进入我们的定义的方法了
            value.__proto__ = arrayMethods;
            if (!shallow){
                this.observeArray(value);
            }
        }
    }
    observeArray(array){
        for(let i=0; i<array.length; i++){
            observe(array[i]);
        }
    }
}
export function observe(value, shallow){
    if (!isObject(value) && !Array.isArray(value)){
        // 不是对象或者数组就直接返回了
        return value;
    }
    if (shouldObserve){
        return new Observer(value, shallow);

    }
}